const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');
const dotenv = require('dotenv');
const helmet = require('helmet');
const morgan = require('morgan');
const http = require('http');
const { Server } = require('socket.io');

// 加载环境变量
dotenv.config();

// 创建Express应用
const app = express();

// 创建HTTP服务器
const server = http.createServer(app);

// 初始化Socket.IO
const io = new Server(server, {
  cors: {
    origin: process.env.FRONTEND_URL || 'http://localhost:5173',
    methods: ['GET', 'POST']
  }
});

// 中间件
app.use(helmet()); // 安全头部
app.use(cors()); // 跨域资源共享
app.use(express.json({ limit: '10mb' })); // JSON解析
app.use(express.urlencoded({ extended: true })); // URL编码解析
app.use(morgan('combined')); // 日志记录

// 数据库连接 - 完全非阻塞式，与服务器启动解耦
try {
  // 尝试连接数据库，但不阻塞服务器启动
  mongoose.connect(process.env.MONGODB_URI || 'mongodb://localhost:27017/activity_organizer', {
    autoIndex: true,
    serverSelectionTimeoutMS: 3000, // 3秒超时
    socketTimeoutMS: 20000,
    family: 4
  }).catch(err => {
    console.error('MongoDB连接尝试失败:', err.message);
    console.log('重要提示: 服务器将继续启动，但数据库相关功能可能不可用');
  });

  const db = mongoose.connection;
  
  // 监听数据库错误
  db.on('error', (error) => {
    console.error('MongoDB连接错误:', error.message);
    console.log('重要提示: 服务器仍在运行，但数据库相关功能可能不可用');
  });
  
  // 监听数据库连接成功
  db.once('open', async () => {
    console.log('MongoDB连接成功');
    
    try {
      // 检查并创建管理员账户
      const User = require('./src/models/User');
      const adminUser = await User.findOne({ role: 'admin' });
      
      if (!adminUser) {
        const newAdmin = new User({
          username: 'admin',
          name: '系统管理员',
          email: 'admin@activity-system.com',
          password: 'admin123', // 初始密码，登录后应更改
          role: 'admin',
          status: 'offline'
        });
        
        await newAdmin.save();
        console.log('========================================');
        console.log('管理员账户创建成功!');
        console.log('- 用户名: admin');
        console.log('- 密码: admin123');
        console.log('- 邮箱: admin@activity-system.com');
        console.log('请在首次登录后立即更改密码!');
        console.log('========================================');
      } else {
        console.log('管理员账户已存在');
      }
    } catch (error) {
      console.error('检查/创建管理员账户失败:', error);
    }
  });
} catch (error) {
  console.error('数据库初始化错误:', error);
  console.log('警告: 数据库连接配置可能有问题，但服务器将继续启动');
}

// 服务器启动与数据库连接完全解耦

// Socket.IO连接处理
io.on('connection', (socket) => {
  console.log('用户连接:', socket.id);
  
  // 用户加入房间
  socket.on('join', (userId) => {
    socket.join(userId);
    console.log(`用户 ${userId} 加入房间`);
    
    // 通知其他用户该用户在线
    socket.broadcast.emit('user-status-change', {
      userId,
      isOnline: true
    });
  });
  
  // 用户断开连接
  socket.on('disconnect', () => {
    console.log('用户断开连接:', socket.id);
  });
  
  // 分组更新通知
  socket.on('group-update', (data) => {
    socket.broadcast.emit('group-updated', data);
  });
});

// 路由
app.use('/api/auth', require('./src/routes/authRoutes'));
app.use('/api/users', require('./src/routes/userRoutes'));
app.use('/api/activities', require('./src/routes/activityRoutes'));
app.use('/api/groups', require('./src/routes/groupRoutes'));

// 健康检查端点
app.get('/health', (req, res) => {
  res.status(200).json({ 
    status: 'OK', 
    timestamp: new Date().toISOString(),
    uptime: process.uptime()
  });
});

// 全局错误处理中间件
app.use((err, req, res, next) => {
  // 避免重复响应
  if (res.headersSent) {
    return next(err);
  }
  
  console.error('未捕获的错误:', err.stack || err);
  
  // 根据错误类型设置适当的状态码
  const statusCode = err.statusCode || 500;
  
  res.status(statusCode).json({
    success: false,
    message: err.message || '服务器内部错误',
    error: process.env.NODE_ENV === 'development' ? {
      message: err.message,
      stack: err.stack
    } : undefined,
    timestamp: new Date().toISOString()
  });
});

// 404 错误处理中间件
app.use('*', (req, res) => {
  res.status(404).json({
    success: false,
    message: '接口不存在',
    path: req.originalUrl,
    timestamp: new Date().toISOString()
  });
});

// 服务器端口
const PORT = process.env.PORT || 3000;

// 启动服务器（不依赖数据库连接成功）
server.listen(PORT, () => {
  console.log(`服务器运行在端口 ${PORT}`);
  console.log(`Socket.IO服务器运行在 ws://localhost:${PORT}`);
});

// 优雅关闭
process.on('SIGINT', async () => {
  console.log('正在关闭服务器...');
  await mongoose.connection.close();
  server.close(() => {
    console.log('服务器已关闭');
    process.exit(0);
  });
});

module.exports = { app, io };